import { _ } from './_lodash-es'

/**
 * @description 只能输入两位小数点且不能以小数点开头
 * @param {*} value
 * @returns
 */
export const priceFormat = (value, int = 100, decimal = 2) => {
  value = value + ''
  // 先把非数字的都替换掉，除了数字和小数点
  value = value.replace(/[^\d.]/g, '')
  // 必须保证第一个为数字而不是小数点
  value = value.replace(/^\./g, '')
  // 如果第二位是数字，第一位不能为0
  value = value.replace(/^0*(\d+)/g, '$1')
  // 保证只有出现一个小数点而没有多个小数点
  value = value.replace(/\.{2,}/g, '.')
  // 保证小数点只出现一次，而不能出现两次以上
  value = value.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')
  // 只能输入两位整数、两位小数，最后一个必须为1-9
  // value = value.replace(/^(\d{0,2})(\d*)(\.?)(\d?)([1-9]?).*$/, '$1$3$4$5')
  // 保证只能输入两个小数，最后一个必须为1-9
  // value = value.replace(/^(\d+)\.(\d?)([1-9]?).*$/, '$1.$2$3')
  const exp = new RegExp(
    '^(\\d{0,' + int + '})(\\d*)(\\.?)(\\d{0,' + (decimal - 1) + '})([1-9]?).*$'
  )
  value = value.replace(exp, '$1$3$4$5')
  return value
}

/**
 * @description 利用canvas下载图片
 * @param {*} imgsrc
 * @param {*} name
 */
export const downloadIamge = (imgsrc, name) => {
  const image = new Image()
  // 解决跨域 Canvas 污染问题
  image.setAttribute('crossOrigin', 'anonymous')
  image.onload = function () {
    const canvas = document.createElement('canvas')
    canvas.width = image.width
    canvas.height = image.height
    const context = canvas.getContext('2d')
    context.drawImage(image, 0, 0, image.width, image.height)
    const url = canvas.toDataURL('image/png') // 得到图片的base64编码数据
    const a = document.createElement('a') // 生成一个a元素
    const event = new MouseEvent('click') // 创建一个单击事件
    a.download = name || 'photo' // 设置图片名称
    a.href = url // 将生成的URL设置为a.href属性
    a.dispatchEvent(event) // 触发a的单击事件
  }
  image.src = imgsrc
}

/**
 * @description 对象字符串序列化容错处理
 * @param {*} val
 * @returns
 */
export const JSONParse = (val) => {
  try {
    return JSON.parse(val)
  } catch (error) {
    return val
  }
}

/**
 * @description 生成二进制长度为128位的数字标识符
 * @return {*}
 */
export const getUUID = () => {
  const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
    const r = (Math.random() * 16) | 0,
      v = c === 'x' ? r : (r & 0x3) | 0x8
    return v.toString(16)
  })
  return uuid.toUpperCase()
}

/**
 * @description 前端vue axios根据服务端返回的文件名和文件流生成文件下载
 * @param {*} data
 * @param} fileName
 */
export const fileExport = (data, fileName) => {
  // 创建当前时间字符串，生成文件名称时使用
  // const time = +new Date()
  if (!fileName) {
    const dis = data.headers['content-disposition']
    fileName = decodeURIComponent(dis.split('attachment;filename=')[1])
  }
  // 转化为blob对象
  const blob = new Blob([data.data || data], {
    type: 'application/octet-stream'
  })
  const urlObject = window.URL || window.webkitURL || window
  // 将blob对象转为一个URL
  const blobURL = urlObject.createObjectURL(blob)
  // 创建一个a标签
  const tempLink = document.createElement('a')
  // 隐藏a标签
  tempLink.style.display = 'none'
  // 设置a标签的href属性为blob对象转化的URL
  tempLink.href = blobURL
  // 给a标签添加下载属性
  tempLink.setAttribute('download', fileName)
  if (typeof tempLink.download === 'undefined') {
    tempLink.setAttribute('target', '_blank')
  }
  // 将a标签添加到body当中
  document.body.appendChild(tempLink)
  // 启动下载
  tempLink.click()
  // 下载完毕删除a标签
  document.body.removeChild(tempLink)
  urlObject.revokeObjectURL(blobURL)
}

/**
 * @description 根据Url下载文件，包括图片
 * @param {*} url
 * @param {*} fileName
 */
export const downloadUrlFile = (url, fileName) => {
  const url2 = url.replace(/\\/g, '/')
  const xhr = new XMLHttpRequest()
  xhr.open('GET', url2, true)
  xhr.responseType = 'blob'
  // xhr.setRequestHeader('Authorization', 'Basic a2VybWl0Omtlcm1pdA==');
  // 为了避免大文件影响用户体验，建议加loading
  xhr.onload = () => {
    if (xhr.status === 200) {
      const blob = xhr.response
      // const type = blob.type.split('/')[1] || ''
      // fileName = fileName + '.' + type
      fileExport(blob, fileName)
    }
  }
  xhr.send()
}

/**
 * @description 获取route.query的参数对象化处理
 * @param {*} data
 * @returns
 */
export const getOtherQuery = (query) => {
  return Object.keys(query).reduce((acc, cur) => {
    if (cur !== 'redirect') {
      acc[cur] = query[cur]
    }
    return acc
  }, {})
}

/**
 * @description 适配iOS的日期显示
 */
export const adapterIOSDate = (val) => {
  return new Date((val + '').replace(/-/g, '/'))
}

/**
 * @description 获取文本的宽度
 * @param {*} data
 * @returns
 */
export const getTableTextWidth = (
  str = '',
  fontSize = '14px',
  padding = 26
) => {
  const dom = document.createElement('span')
  dom.style.display = 'inline-block'
  dom.style.fontSize = fontSize
  dom.textContent = str
  document.body.appendChild(dom)
  const width = dom.clientWidth + padding + 1
  document.body.removeChild(dom)
  return width
}

/**
 * @description 小屏的判断
 * @param {*} data
 * @returns
 */
export const isSmallNotebook = (maxWidth = 1750) => {
  return window.innerWidth <= maxWidth
}

/**
 * @description 获取文本的宽度
 * @param {*} data
 * @returns
 */
export const getLabelWidth = (str = '', obj = {}) => {
  const { fontSize = '14px', padding = 26, border = 25 } = obj
  const dom = document.createElement('span')
  dom.style.display = 'inline-block'
  dom.style.fontSize = fontSize
  dom.textContent = str
  document.body.appendChild(dom)
  const width = dom.clientWidth + padding + border
  document.body.removeChild(dom)
  return width + 'px'
}

/**
 * @description 处理无值时显示对应字符
 * @param {*} data
 * @returns
 */
export const handlerItemData = (data, string = '-') => {
  return !data && data !== 0 ? string : data
}

/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(func, wait, immediate = false) {
  let timeout, args, context, timestamp, result

  const later = function () {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }

  return function (...args) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延时不存在，重新设定延时
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }

    return result
  }
}
